package com.yunshipei.common;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;

import com.yunshipei.common.net.converter.JsonConverterFactory;
import com.yunshipei.core.common.XCloudException;
import com.yunshipei.core.net.EnterClient;
import com.yunshipei.core.utils.FileUtils;

import org.json.JSONObject;
import org.reactivestreams.Publisher;

import java.io.File;
import java.io.InputStream;

import io.reactivex.Flowable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

public class ProfileResHandler {

    private Context mContext;
    private String mManagerServer;

    private Api mApi;
    private SharedPreferences mCfgPreference;

    public ProfileResHandler(Context mContext, String mManagerServer) {
        this.mContext = mContext;
        this.mManagerServer = mManagerServer;
        this.mCfgPreference = mContext.getSharedPreferences(ProfileHandler.H5_PKG_CONFIG, Context.MODE_PRIVATE);
        OkHttpClient okHttpClient = EnterClient.getInstances().getManagerClient();
        this.mApi = new Retrofit.Builder().baseUrl(mManagerServer).client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(JsonConverterFactory.create()).build().create(Api.class);
    }

    //通讯录h5包的下载处理逻辑，返回通讯录的加载链接
    public Flowable<String> contactsPageFlowable(final int newVersion, final String url) {
        return Flowable.just(true).flatMap(new Function<Boolean, Publisher<String>>() {
            @Override
            public Publisher<String> apply(Boolean aBoolean) throws Exception {
                String downloadUrl = url;
                if (!downloadUrl.startsWith("http://") && !downloadUrl.startsWith("https://")) {
                    downloadUrl = mManagerServer + File.separator + downloadUrl;
                }
                String resJSON = FileUtils.readAssertResource(mContext, "local/localResCfg.json");
                if (TextUtils.isEmpty(resJSON)) {
                    return Flowable.error(new XCloudException("获取本地通讯录资源文件的配置失败"));
                }
                JSONObject localCfgObject = new JSONObject(resJSON);
                int localVersion = localCfgObject.optInt("addressbookpage", 0);
                if (newVersion <= localVersion) {
                    return Flowable.just("file:///android_asset/local/addressbookpage/index.html");
                }
                //下载最新的通讯录
                int contactVersion = mCfgPreference.getInt("_h5_contact_version", 0);
                File indexFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_contacts" + File.separator + "index.html");
                if (0 == contactVersion || newVersion != contactVersion || !indexFile.exists()) {
                    return mApi.commonDownload(downloadUrl).flatMap(new Function<Response<ResponseBody>, Publisher<String>>() {
                        @Override
                        public Publisher<String> apply(Response<ResponseBody> response) throws Exception {
                            int code = response.code();
                            if (code != 200) {
                                return Flowable.error(new XCloudException(response.message()));
                            }
                            File newFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_contacts_temp");
                            boolean success = FileUtils.unZipStream(response.body().byteStream(), newFile.getPath());
                            if (success) {
                                InputStream is = mContext.getAssets().open("local/addressbookpage/addressBookVendor.js");
                                boolean isSuccess = FileUtils.writeToFile(newFile.getPath(), "addressBookVendor.js", is);
                                if (isSuccess) {
                                    File finalFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_contacts");
                                    FileUtils.deletePathReal(finalFile.getPath());
                                    boolean rename = newFile.renameTo(finalFile);
                                    if (rename) {
                                        mCfgPreference.edit().putInt("_h5_contact_version", newVersion).apply();
                                        return Flowable.just("file://" + finalFile.getAbsolutePath() + File.separator + "index.html");
                                    } else {
                                        return Flowable.error(new XCloudException("通讯录重命名失败"));
                                    }
                                } else {
                                    return Flowable.error(new XCloudException("通讯录通用资源复制失败"));
                                }
                            } else {
                                return Flowable.error(new XCloudException("通讯录资源解压失败..."));
                            }
                        }
                    }).doOnError(new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            FileUtils.deletePathReal(mContext.getFilesDir().getParent() + File.separator + "web_contacts_temp");
                        }
                    });
                } else {
                    return Flowable.just("file://" + mContext.getFilesDir().getParent() + File.separator + "web_contacts" + File.separator + "index.html");
                }
            }
        });
    }

    //我的h5页面包处理逻辑，返回页面加载的链接
    public Flowable<String> mePageFlowable(final int newVersion, final String url) {
        return Flowable.just(true).flatMap(new Function<Boolean, Publisher<String>>() {
            @Override
            public Publisher<String> apply(Boolean aBoolean) throws Exception {
                String downloadUrl = url;
                if (!downloadUrl.startsWith("http://") && !downloadUrl.startsWith("https://")) {
                    downloadUrl = mManagerServer + File.separator + downloadUrl;
                }
                String resJSON = FileUtils.readAssertResource(mContext, "local/localResCfg.json");
                if (TextUtils.isEmpty(resJSON)) {
                    return Flowable.error(new XCloudException("获取本地我的资源文件的配置失败"));
                }
                JSONObject localCfgObject = new JSONObject(resJSON);
                int localVersion = localCfgObject.optInt("mepage", 0);
                if (newVersion <= localVersion) {
                    return Flowable.just("file:///android_asset/local/mepage/index.html");
                }
                //下载最新的通讯录
                int contactVersion = mCfgPreference.getInt("_h5_me_version", 0);
                File indexFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_me" + File.separator + "index.html");
                if (0 == contactVersion || newVersion != contactVersion || !indexFile.exists()) {
                    return mApi.commonDownload(downloadUrl).flatMap(new Function<Response<ResponseBody>, Publisher<String>>() {
                        @Override
                        public Publisher<String> apply(Response<ResponseBody> response) throws Exception {
                            int code = response.code();
                            if (code != 200) {
                                return Flowable.error(new XCloudException(response.message()));
                            }
                            File newFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_me_temp");
                            boolean success = FileUtils.unZipStream(response.body().byteStream(), newFile.getPath());
                            if (success) {
                                InputStream is = mContext.getAssets().open("local/mepage/meVendor.js");
                                boolean isSuccess = FileUtils.writeToFile(newFile.getPath(), "meVendor.js", is);
                                if (isSuccess) {
                                    File finalFile = new File(mContext.getFilesDir().getParent() + File.separator + "web_me");
                                    FileUtils.deletePathReal(finalFile.getPath());
                                    boolean rename = newFile.renameTo(finalFile);
                                    if (rename) {
                                        mCfgPreference.edit().putInt("_h5_me_version", newVersion).apply();
                                        return Flowable.just("file://" + finalFile.getAbsolutePath() + File.separator + "index.html");
                                    } else {
                                        return Flowable.error(new XCloudException("我的重命名失败"));
                                    }
                                } else {
                                    return Flowable.error(new XCloudException("我的通用资源复制失败"));
                                }
                            } else {
                                return Flowable.error(new XCloudException("我的资源解压失败..."));
                            }
                        }
                    }).doOnError(new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            FileUtils.deletePathReal(mContext.getFilesDir().getParent() + File.separator + "web_me_temp");
                        }
                    });
                } else {
                    return Flowable.just("file://" + mContext.getFilesDir().getParent() + File.separator + "web_me" + File.separator + "index.html");
                }
            }
        });
    }

    interface Api {
        @GET
        @Streaming
        Flowable<Response<ResponseBody>> commonDownload(@Url String url);
    }
}
